﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace BtLibs
{
    public delegate void LogDelegate(string msg, Exception e = null);
    public interface ILog
    {
        void Log(string msg, Exception e = null);
    }
    public class FileLog : ILog
    {
        FileInfo file;
        string fileName;
        //这里或许可以添加特定模式.懒得做了...
        public FileLog(string file, bool autoFlush = true)
        {
            this.file = new FileInfo(file);
            this.fileName = this.file.FullName;
            EnsureDirExists();
        }
        private void EnsureDirExists()
        {
            if (!this.file.Directory.Exists)
            { this.file.Directory.Create(); }
        }
        #region ILog 成员
        public void Log(string msg, Exception e = null)
        {
            msg = msg + "\n" + (e == null ? "" : e.ToString() + "\n");
            lock (this)
            {
                File.AppendAllText(this.fileName, msg, Encoding.UTF8);
            }
        }
        #endregion
    }

    public class ConsoleLog : ILog
    {
        static ConsoleLog instance = new ConsoleLog();
        public static ConsoleLog Instance { get { return instance; } }
        #region ILog 成员
        public void Log(string msg, Exception e = null)
        {
            Console.WriteLine(msg);
            if (e != null)
            { Console.WriteLine(e.ToString()); }
        }
        #endregion
    }

    public class DelegateLog : ILog
    {
        public event LogDelegate logEvent;
        #region ILog 成员
        public void Log(string msg, Exception e = null)
        {
            logEvent(msg, e);
        }
        #endregion
    }

    public class CommonLog : ILog
    {
        private List<ILog> logs = new List<ILog>();
        private DelegateLog delegateLog = new DelegateLog();
        public CommonLog()
        {
            delegateLog.logEvent += ConsoleLog.Instance.Log;
            AddLog(delegateLog);
        }
        public void AddLog(ILog log)
        {
            this.logs.Add(log);
        }
        public void AddLog(LogDelegate log)
        {
            delegateLog.logEvent += log;
        }
        #region ILog 成员
        public void Log(string msg, Exception e = null)
        {
            foreach (ILog log in logs)
            {
                log.Log(msg, e);
            }
        }
        #endregion
    }
    /// <summary>
    /// 两种方式添加Log（ILog接口 + LogDelegate）
    /// </summary>
    public class DefaultLogger : CommonLog
    {
        public static DefaultLogger Instance = new DefaultLogger();
    }
}
